home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Interfaces / PInterfaces / UMenuSetup.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  12.2 KB  |  291 lines  |  [TEXT/MPS ]

  1. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  2. { UMenuSetup.p }
  3. { Copyright © 1984-1990 Apple Computer Inc.  All rights reserved. }
  4.  
  5. {[f-]}
  6. {
  7.             T H E O R Y   O F     O P E R A T I O N
  8.  
  9. This unit provides two features:  It implements a command numbering
  10. system that is independent of menu/item placement, and implements a
  11. framework for optimizing menu setups.
  12.  
  13. The command numbering system works by assigning commands a unique
  14. integer number, and providing a mechanism for mapping command numbers
  15. to menu/item pairs.  A set of routines are provide to manipulate
  16. commands via their command number rather than their menu and item
  17. numbers.
  18.  
  19. Each command can be assigned an integer command number from 1 to
  20. 32767.    To associate a command number with a menu item, menu resources
  21. are defined with the 'cmnu' resource type--not the 'MENU' type.  The
  22. 'cmnu' type is just like the 'MENU' type, with an additional command
  23. number field for each menu item.  The PostRez Tool converts the
  24. 'cmnu' output of Rez into equivalent 'MENU' resources and one 'mntb'
  25. resource.    The 'mntb' resource maps command numbers to menu/item pairs.
  26.  
  27. The items of some menus cannot be determined until run-time.  The font
  28. menu is an example.  In such cases, no command number is assigned by
  29. you.  Instead, the command number is equal to -(256 * menu + item).
  30.  
  31. The procedure CmdToMenuItem converts a command number to a menu id
  32. and item number by the following method:
  33.  
  34. - If the command number is positive, the command table is searched
  35. for the number. If it is found, CmdToMenuItem returns the corre-
  36. sponding menu id and item number.  Otherwise the menu and item are
  37. zero.
  38.  
  39. - If the command number is negative, the menu number is the upper eight
  40. bits, and the item number the lower eight bits, of the absolute value
  41. of the command number.    (This implies that menu id's must be <= 127
  42. and item numbers must be <= 255.)
  43.  
  44. The function CmdFromMenuItem converts menu/items to command numbers by
  45. the following method:
  46.  
  47. - If the item number is positive, the command table is search for the
  48. given menu/item pair.  If found, the corresponding command number is
  49. returned.  If not found, the number returned is equal to
  50. -(256 * menu + item).
  51.  
  52. - If the item number is negative, the number returned is equal to
  53. -item number.
  54.  
  55. Note that CmdToMenuItem and CmdFromMenuItem work regardless of whether
  56. the command is actually installed in the menu bar.    MacApp takes
  57. advantage of this feature by having a set of generic "buzz" commands,
  58. whose primary use is to set the name of the Undo command (e.g. 'Undo
  59. Drawing').
  60.  
  61. The second feature of this unit is to optimize menu setups (changing
  62. the appearance of menus and items).  Normally, each call to CheckItem,
  63. SetItemStyle and SetCmdIcon in turn calls CalcMenuSize because the width
  64. or height of the menu may have changed.  If menu setups are done all at
  65. one time, then CalcMenuSize can be deferred until the end of the setup
  66. process.  The procedure PerformMenuSetup implements this mechanism.  It
  67. relies on the fact that menu setups are done all at once, and that you
  68. will call SetCmdName, SetItemStyle and SetCmdIcon instead of SetItem,
  69. SetItemStyle and SetCmdIcon.  It works only for menus whose id is from
  70. 1 to mLastMenu.  Menus with IDs greater than mLastMenu are not affected
  71. by this scheme.
  72.  
  73. PerformMenuSetup accepts one parameter, a procedure which actually
  74. implements the menu appearance changes.  SetupMenus performs the
  75. following steps:
  76.  
  77. - Before calling your menu setup procedure, StartupMenuSetup is called.
  78. It disables all menus and items, remembers the current
  79. menu proc and enabled flags of each menu, and sets the MenuProc of
  80. each menu to gHNullMenuProc, thereby disabling CalcMenuSize.
  81. - Your procedure is called.  It in turn calls SetCmdName,
  82. SetCmdStyle, SetCmdIcon, Enable, EnableCheck, or a
  83. Toolbox routine (provided it isn't SetItem, SetItemStyle or
  84. SetCmdIcon).
  85. - Menus with at least one enabled item are enabled, CalcMenuSize is
  86. called for those menus that need it, each menu's menuproc is restored,
  87. and DrawMenuBar is called if the enabled state of any menu changed.
  88. }
  89. {[f+]}
  90.  
  91. {$IFC UNDEFINED UsingIncludes}
  92. {$SETC UsingIncludes := FALSE}
  93. {$ENDC}
  94.  
  95. {$IFC NOT UsingIncludes}
  96. UNIT UMenuSetup;
  97.  
  98.     INTERFACE
  99.         {$ENDC}
  100.  
  101.         {$IFC UNDEFINED __UMenuSetup__}
  102.         {$SETC __UMenuSetup__ := FALSE}
  103.         {$ENDC}
  104.  
  105.         {$IFC NOT __UMenuSetup__}
  106.         {$SETC __UMenuSetup__ := TRUE}
  107.  
  108.         { • Required for this unit's interface. Auto-Include them }
  109.         {$SETC UMenuSetupIncludes := UsingIncludes}
  110.         {$SETC UsingIncludes := TRUE}
  111.         {$I+}
  112.         {$IFC UNDEFINED UsingTypes} {$I Types.p} {$ENDC}
  113.         {$IFC UNDEFINED UsingMenus} {$I Menus.p} {$ENDC}
  114.         {$SETC UsingIncludes := UMenuSetupIncludes}
  115.  
  116.         CONST
  117.             kMNTBbyCmdNumber    = 'mntb';                { menu command number table type }
  118.             kIDMNTBbyCmdNumber    = 128;                    { menu command number table ID }
  119.  
  120.             mFirstMenu            = 1;                    { MacApp manages menu titles
  121.                                                          mFirstMenu..mLastMenu generically }
  122.             mApple                = mFirstMenu;            { MacApp does not disable any commands in
  123.                                                          this menu }
  124.             mFile                = mApple + 1;            { Default ID of the File menu }
  125.             mEdit                = mFile + 1;            { Default ID of the Edit menu }
  126.  
  127.             mDebug                = 900;                    { read in if debugging is turned on; number
  128.                                                          corresponds with debugging command numbers
  129.                                                          }
  130.             mLastMenu            = 63;                    { MacApp disables menu titles
  131.                                                          mFile..mLastMenu generically }
  132.  
  133.         TYPE
  134.  
  135.             CmdNumber            = INTEGER;                { CmdNumbers tell MacApp what verb is
  136.                                                          intended after mapping from menu/item. }
  137.  
  138.         VAR
  139.             gMenusAreSetup:     BOOLEAN;                { set FALSE before every event; set TRUE by
  140.                                                          SetupTheMenus, which is called at Idle
  141.                                                          Begin; if your DoIdle changes the target
  142.                                                          or makes other changes that would alter
  143.                                                          the appearance of menus, you must set
  144.                                                          gMenusAreSetup to FALSE there. }
  145.             gRedrawMenuBar:     BOOLEAN;                { if TRUE, then DrawMenuBar will be called
  146.                                                          by TApplication.SetupTheMenus. If you have
  147.                                                          menus that are not handled by MacApp, your
  148.                                                          implementation(s) of DoSetupMenus can set
  149.                                                          this to TRUE to force the menu bar to be
  150.                                                          redrawn. }
  151.             {$IFC qDebug}
  152.             gTraceSetupMenus:    BOOLEAN;
  153.             {$ENDC}
  154.  
  155.         { The following routines all recognize command numbers of the form -(256 * menu + item) and
  156.         -(256 * menu). The former is used when there is no command number; the latter to
  157.         enable/disable a whole menu (rare) }
  158.  
  159.         FUNCTION CmdEnabled(cmd: CmdNumber): BOOLEAN;
  160.         { Returns true if the given cmd is currently enabled. }
  161.  
  162.         FUNCTION CmdFromMenuItem(menu, item: INTEGER): CmdNumber;
  163.         { Returns the command number for the given menu ID and item number. If the item number is
  164.         positive, the command table is search for the given menu/item pair. If found, the
  165.         corresponding command number is returned. If not found, the number returned is equal to
  166.         -(256 * menu + item). If the item number is negative, the number returned is equal to -item
  167.         number. }
  168.  
  169.         PROCEDURE CmdToMenuItem(aCmd: CmdNumber;
  170.                                 VAR menu, item: INTEGER);
  171.         { CmdToMenuItem returns the menu ID and item number of the given command. If aCmd is
  172.         positive, the command table is searched for aCmd. If it is found, CmdToMenuItem returns the
  173.         corresponding menu ID and item number. Otherwise menu and item are set to zero. If aCmd is
  174.         negative, the menu number is the upper eight bits, and the item number the lower eight
  175.         bits, of the absolute value of aCmd. (This implies that menu id's must be <= 127 and item
  176.         numbers must be <= 255.) }
  177.  
  178.         FUNCTION CmdToComponents(cmd: CmdNumber; VAR menuNo, itemNo: integer): MenuHandle;
  179.         { CmdToComponents returns the menu ID and item number of the given command. as well as
  180.         the MenuHandle if the cmd exists.  Otherwise it returns nil. }
  181.  
  182.         PROCEDURE CmdToName(aCmd: CmdNumber;
  183.                             VAR menuText: Str255);
  184.         { Return the text of the menu item for the given command. }
  185.  
  186.         PROCEDURE EachMenuDo(PROCEDURE DoToMenu(aMenuHandle: MenuHandle;
  187.                             isHierarchical: Boolean); includeHierarchical: Boolean);
  188.         { Sequences thru each menu in menu bar with ID in [0..mLastMenu], calling DoToMenu for each
  189.         menu. Handles mDebug as a special case. }
  190.  
  191.         PROCEDURE Enable(aCmd: CmdNumber;
  192.                          canDo: BOOLEAN);
  193.         { Enable or disable a command }
  194.  
  195.         PROCEDURE EnableCheck(aCmd: CmdNumber;
  196.                               canDo: BOOLEAN;
  197.                               checkIt: BOOLEAN);
  198.         { Enable/Disable and check/uncheck a command }
  199.  
  200.         FUNCTION GetResMenu(menuResID: INTEGER): MenuHandle;
  201.         { Utility that just does GetResource('MENU', resourceID), so that it works for menus not
  202.         currently in the menu bar. (You cannot call GetMenu more than once for the same menu, so
  203.         you can use this (or MAGetMenu which is preferred) instead.) }
  204.  
  205.         PROCEDURE InitUMenuSetup;
  206.         { Initializes this unit, and must be called before using any other part of this unit. Loads
  207.         the command table and sets up the null menu proc. }
  208.  
  209.         FUNCTION MAGetNewMBar(menuRsrcID: INTEGER): Handle;
  210.         { Equivalent to the Menu Manager's GetNewMBar except it explicitly sets the menu bar's
  211.         colors.}
  212.  
  213.         PROCEDURE MAInsertMenu(theMenu: MenuHandle;
  214.                                beforeID: INTEGER);
  215.         { Equivalent to the Menu Manager's InsertMenu with the addition that the MAInsertMenu looks
  216.         for an 'mctb' resource whose id is the menu's id, and if it is present applies the 'mctb'
  217.         to the menu.}
  218.  
  219.         FUNCTION MAGetMenu(menuNo: INTEGER): MenuHandle;
  220.         { Not quite equivalent to GetMenu because it doesn't load the menuDefProc or color table yet.
  221.         It does, however, let you get the menuhandle without calling GetMenu more than once.  It tries
  222.         the menubar first and then calls GetResMenu if necessary. }
  223.  
  224.         PROCEDURE NeedCalcMenuSize(aMenuHandle: MenuHandle);
  225.         { This procedure is called as part of the menu setup process and indicates that the given
  226.         menu needs CalcMenuSize. You must explicitly call this if you use change a menu by means
  227.         other than those supplied in this unit (e.g. you insert or delete items from a menu).
  228.         Failure to do so will result in improperly sized menus. }
  229.  
  230.         PROCEDURE SetCmdIcon(aCmd: CmdNumber;
  231.                              menuIcon: Byte);
  232.         { You should call this (instead of the Toolbox's SetCmdIcon) for menus that are in the range
  233.         [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
  234.         needs to be recomputed. }
  235.  
  236.         PROCEDURE SetCmdName(aCmd: CmdNumber;
  237.                              menuText: Str255);
  238.         { You should call this (instead of the Toolbox's SetItem) for menus that are in the range
  239.         [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
  240.         needs to be recomputed. }
  241.  
  242.         PROCEDURE SetIndCmdName(aCmd: CmdNumber;
  243.                                 rsrcID, strIndex: INTEGER);
  244.         { Does a GetIndString with the rsrcID & strIndex; and then a SetCmdName. }
  245.  
  246.         PROCEDURE SetMenuState(aCmd: CmdNumber;
  247.                                rsrcID, falseBuzzItem, trueBuzzItem: INTEGER;
  248.                                stateVariable: BOOLEAN);
  249.         { IF stateVariable THEN
  250.             SetIndCmdName(aCmd, rsrcID, trueBuzzItem)
  251.         ELSE
  252.             SetIndCmdName(aCmd, rsrcID, falseBuzzItem);
  253.         }
  254.  
  255.         PROCEDURE SetStyle(aCmd: CmdNumber;
  256.                            aStyle: Style);
  257.         { You should call this (instead of the Toolbox's SetItemStyle) for menus that are in the
  258.         range [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's
  259.         size needs to be recomputed. }
  260.  
  261.         PROCEDURE PerformMenuSetup(PROCEDURE TheMenuSetterUpper);
  262.         { Routine that perfoms the menu setup. }
  263.  
  264.         PROCEDURE InvalidateMenus;
  265.         { Invalidate all the items on all the menus.  Just like invalidation for windows it doesn't
  266.         immediately change the visual appearance when you invalidate, it just means they are invalid
  267.         and should be "setup" before showing them to the user again.  }
  268.  
  269.         PROCEDURE ValidateMenus;
  270.         { Validate all the items on all the menus.    Just like Validation for windows it doesn't
  271.         immediately change the visual appearance when you Validate, it just means they don't need
  272.         to be changed before showing them to the user again.  }
  273.  
  274.         FUNCTION MenusHavePendingUpdate: BOOLEAN;
  275.         { TRUE if the menus are invalid and should be "setup" before showing them to the user.    }
  276.  
  277.         PROCEDURE InvalidateMenuBar;
  278.         { Invalidate the menu bar.    It should be redrawn again.  }
  279.  
  280.         PROCEDURE ValidateMenuBar;
  281.         { Validate the menu bar.  It doesn't need redrawing, its just fine thank you.  }
  282.  
  283.         FUNCTION MenuBarHasPendingUpdate: BOOLEAN;
  284.         { TRUE if the menu bar is invalid and should be redrawn.  }
  285.  
  286.         {$ENDC}
  287.  
  288.         {$IFC NOT UsingIncludes}
  289. END.
  290. {$ENDC}
  291.